﻿package kit4j.util.lang;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串工具类。提供针对字符串对象的各种常用测试验证方法。
 * 
 * @author MiniKnife
 * 
 */
public abstract class StringUtil {

	/**
	 * 单例对象持有者。
	 * 
	 * @author MiniKnife
	 * 
	 */
	private static class SingletonHolder {

		private static Pattern blankPattern = Pattern.compile("\\s*?");

		/**
		 * @return 匹配空白字符串的正则表达式的Pattern对象。
		 */
		static Pattern getBlankPattern() {
			return blankPattern;
		}
		
	}

	/**
	 * 判断指定字符串是否为空。
	 * 
	 * @param str
	 *            要判断的字符串
	 * @return 如果指定的字符串为null或者空字符窜，返回true，否则返回false。
	 */
	public static boolean isEmpty(String str) {
		return str == null || str.length() == 0;
	}

	/**
	 * 判断指定字符串是否不为空。
	 * 
	 * @param str
	 *            要判断的字符串
	 * @return 如果指定的字符串不为null且不是空字符窜，返回true，否则返回false。
	 */
	public static boolean isNotEmpty(String str) {
		return !isEmpty(str);
	}

	/**
	 * 判断指定多个字符串是否都为空。
	 * 
	 * @param str
	 *            要判断的字符串
	 * @return 如果指定的多个字符串都为null或者空字符窜，返回true，否则返回false。
	 */
	public static boolean areEmpty(String... strings) {
		for (String s : strings) {
			if (isNotEmpty(s)) {
				return false;
			}
		}

		return true;
	}

	/**
	 * 判断指定多个字符串是否都不为空。
	 * 
	 * @param str
	 *            要判断的字符串
	 * @return 如果指定的多个字符串都不为null且都不是空字符窜，返回true，否则返回false。
	 */
	public static boolean areNotEmpty(String... strings) {
		for (String s : strings) {
			if (isEmpty(s)) {
				return false;
			}
		}

		return true;
	}

	/**
	 * 判断指定的字符串是否为空白字符串。
	 * 
	 * @param str
	 *            要判断的字符串
	 * @return 如果指定的字符串为空(见{@link #isEmpty(String) isEmpty(String)})或者全部为非打印字符，返回true，否则返回false。
	 */
	public static boolean isBlank(String str) {
		if (isEmpty(str)) {
			return true;
		} else {
			Pattern blankPattern = getBlankPattern();
			Matcher matcher = blankPattern.matcher(str);

			return matcher.matches();
		}
	}

	/**
	 * @return 匹配空白字符串的正则表达式的Pattern对象。
	 */
	private static Pattern getBlankPattern() {
		return SingletonHolder.getBlankPattern();
	}

	/**
	 * 判断指定的字符串是否不为空白字符串。
	 * 
	 * @param str
	 *            要判断的字符串
	 * @return 如果指定的字符串不为空(见{@link #isEmpty(String) isEmpty(String)})且包含打印字符，返回true，否则返回false。
	 */
	public static boolean isNotBlank(String str) {
		return !isBlank(str);
	}

	/**
	 * 判断指定的多个字符串是否都为空白字符串。
	 * 
	 * @param strings
	 *            要判断的字符串
	 * @return 如果指定的字符串都为空(见{@link #isEmpty(String) isEmpty(String)})或者全部为非打印字符，返回true，否则返回false。
	 */
	public static boolean areBlank(String... strings) {
		for (String s : strings) {
			if (isNotBlank(s)) {
				return false;
			}
		}

		return true;
	}

	/**
	 * 判断指定的多个字符串是否都不为空白字符串。
	 * 
	 * @param strings
	 *            要判断的字符串
	 * @return 如果指定的字符串都不为空(见{@link #isEmpty(String) isEmpty(String)})且都包含打印字符，返回true，否则返回false。
	 */
	public static boolean areNotBlank(String... strings) {
		for (String s : strings) {
			if (isBlank(s)) {
				return false;
			}
		}

		return true;
	}

	/**
	 * 将给定位置的字符替换为大写形式。
	 * 
	 * @param builder
	 *            要进行更改的StringBuilder对象
	 * @param index
	 *            要转换的字符的索引
	 * @return 进行替换后的StringBuilder对象。
	 */
	public static StringBuilder replaceWithUpperCase(StringBuilder builder, int index) {
		builder.setCharAt(index, Character.toUpperCase(builder.charAt(index)));
		return builder;
	}

	/**
	 * 将字符串中给定位置的字符替换为大写形式。
	 * 
	 * @param str
	 *            要进行更改的字符串
	 * @param index
	 *            要转换的字符的索引
	 * @return 进行替换后的字符串对象。
	 */
	public static String replaceWithUpperCase(String str, int index) {
		return replaceWithUpperCase(new StringBuilder(str), index).toString();
	}
	
	/**
	 * 将给定位置的字符替换为小写形式。
	 * 
	 * @param builder
	 *            要进行更改的StringBuilder对象
	 * @param index
	 *            要转换的字符的索引
	 * @return 进行替换后的StringBuilder对象。
	 */
	public static StringBuilder replaceWithLowerCase(StringBuilder builder, int index) {
		builder.setCharAt(index, Character.toLowerCase(builder.charAt(index)));
		return builder;
	}
	
	/**
	 * 将字符串中给定位置的字符替换为小写形式。
	 * 
	 * @param str
	 *            要进行更改的字符串
	 * @param index
	 *            要转换的字符的索引
	 * @return 进行替换后的字符串对象。
	 */
	public static String replaceWithLowerCase(String str, int index) {
		return replaceWithLowerCase(new StringBuilder(str), index).toString();
	}
}
